﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using BarStructures;
using BarStructures.Analysers;
using BarStructures.Deformed;
using System.Collections;

namespace BarStructuresAnalysis
{
    public partial class Form1 : Form
    {
        Model _Model = null;
        Analyser _Analyser1 = null;
        Analyser _Analyser2 = null;

        List<double> eigenValuesCache1 = null;
        List<double> eigenValuesCache2 = null;


        public Form1()
        {
            InitializeComponent();
        }
        
        /// <summary> Очистка обоих списков. </summary>
        private void ClearLists()
        {
            evalsList1.Items.Clear();
            evalsList2.Items.Clear();
        }

        /// <summary> Расчёт собственных значений для обоих анализаторов. </summary>
        private void mnuAnalyse_Click(object sender, EventArgs e)
        {
            if (_Model != null)
            {
                if (_Analyser1 != null)
                {
                    evalsList1.Items.Clear();
                    _Analyser1.Analyse();
                    eigenValuesCache1 = _Analyser1.GetEigenValuesList();
                    evalsList1.BeginUpdate();
                    for (int i = 0; i < eigenValuesCache1.Count; i++)
                        evalsList1.Items.Add(eigenValuesCache1[i].ToString("E6"));
                    evalsList1.EndUpdate();
                }
                if (_Analyser2 != null)
                {
                    evalsList2.Items.Clear();
                    _Analyser2.Analyse();
                    eigenValuesCache2 = _Analyser2.GetEigenValuesList();
                    evalsList2.BeginUpdate();
                    for (int i = 0; i < eigenValuesCache2.Count; i++)
                        evalsList2.Items.Add(eigenValuesCache2[i].ToString("E6"));
                    evalsList2.EndUpdate();
                }
            }
        }

        /// <summary> Отображение деформированного состояния для СЗ первого анализатора. </summary>
        private void evalsList1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (evalsList1.FocusedItem != null && _Analyser1 != null && eigenValuesCache1 != null)
            {
                DeformedState deformedState = _Analyser1.GetDeformedStateForEigenValue(eigenValuesCache1[evalsList1.FocusedItem.Index]);
                if (deformedState != null)
                    drawBoard.DrawableModel = deformedState;
            }
        }

        /// <summary> Отображение деформированного состояния для СЗ второго анализатора. </summary>
        private void evalsList2_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (evalsList2.FocusedItem != null && _Analyser2 != null && eigenValuesCache2 != null)
            {
                DeformedState deformedState = _Analyser2.GetDeformedStateForEigenValue(eigenValuesCache2[evalsList2.FocusedItem.Index]);
                if (deformedState != null)
                    drawBoard.DrawableModel = deformedState;
            }
        }

        /// <summary> Копирование списка собственных значений в буффер обмена. </summary>
        private void mnuCopyEvalsToBuffer_Click(object sender, EventArgs e)
        {
            if (cmnuLists.SourceControl.AccessibleName == "Analyser1")
            {
                if (eigenValuesCache1.Count > 0)
                {
                    double[] evals = eigenValuesCache1.ToArray();
                    Array.Sort<double>(evals);
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < evals.Length; i++)
                        sb.Append(evals[i].ToString("E6") + "\r\n");
                    Clipboard.Clear();
                    Clipboard.SetText(sb.ToString(), TextDataFormat.Text);
                }
            }
            else
            {
                if (eigenValuesCache2.Count > 0)
                {
                    double[] evals = eigenValuesCache2.ToArray();
                    Array.Sort<double>(evals);
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < evals.Length; i++)
                        sb.Append(evals[i].ToString("E6") + "\r\n");
                    Clipboard.Clear();
                    Clipboard.SetText(sb.ToString(), TextDataFormat.Text);
                }
            }
        }
        
        /// <summary> Копирование списка значений расчётного СВ в буффер обмена. </summary>
        private void mnuCopyToBufferEvec_Click(object sender, EventArgs e)
        {
            if (cmnuLists.SourceControl.AccessibleName == "Analyser1")
            {
                if (evalsList1.FocusedItem != null && _Analyser1 != null && eigenValuesCache1 != null)
                {
                    StringBuilder sb = new StringBuilder();
                    List<double> evecs = _Analyser1.GetEigenVecsListForEigenValue(eigenValuesCache1[evalsList1.FocusedItem.Index]);

                    if (evecs != null)
                        for (int i = 0; i < evecs.Count; i++)
                            sb.Append(evecs[i].ToString("E6") + "\r\n");

                    Clipboard.Clear();
                    Clipboard.SetText(sb.ToString(), TextDataFormat.Text);
                }
            }
            else
            {
                if (evalsList2.FocusedItem != null && _Analyser2 != null && eigenValuesCache2 != null)
                {
                    StringBuilder sb = new StringBuilder();
                    List<double> evecs = _Analyser2.GetEigenVecsListForEigenValue(eigenValuesCache2[evalsList2.FocusedItem.Index]);

                    if (evecs != null)
                        for (int i = 0; i < evecs.Count; i++)
                            sb.Append(evecs[i].ToString("E6") + "\r\n");

                    Clipboard.Clear();
                    Clipboard.SetText(sb.ToString(), TextDataFormat.Text);
                }
            }
        }

        /// <summary> Копирование списка значений полного СВ в буффер обмена. </summary>
        private void mnuCopyToBufferFullEvec_Click(object sender, EventArgs e)
        {
            if (cmnuLists.SourceControl.AccessibleName == "Analyser1")
            {
                if (evalsList1.FocusedItem != null && _Analyser1 != null && eigenValuesCache1 != null)
                {
                    StringBuilder sb = new StringBuilder();
                    List<double> evecs = _Analyser1.GetFullEigenVecsListForEigenValue(eigenValuesCache1[evalsList1.FocusedItem.Index]);

                    if (evecs != null)
                        for (int i = 0; i < evecs.Count; i++)
                            sb.Append(evecs[i].ToString("E6") + "\r\n");

                    Clipboard.Clear();
                    Clipboard.SetText(sb.ToString(), TextDataFormat.Text);
                }
            }
            else
            {
                if (evalsList2.FocusedItem != null && _Analyser2 != null && eigenValuesCache2 != null)
                {
                    StringBuilder sb = new StringBuilder();
                    List<double> evecs = _Analyser2.GetFullEigenVecsListForEigenValue(eigenValuesCache2[evalsList2.FocusedItem.Index]);

                    if (evecs != null)
                        for (int i = 0; i < evecs.Count; i++)
                            sb.Append(evecs[i].ToString("E6") + "\r\n");

                    Clipboard.Clear();
                    Clipboard.SetText(sb.ToString(), TextDataFormat.Text);
                }
            }
        }

        /// <summary> Масштабирование деформаций. </summary>
        private void drawBoard_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && drawBoard.DrawableModel is DeformedState)
            {
                if (e.KeyCode == Keys.Up)
                    ((DeformedState)drawBoard.DrawableModel).Scale += 0.1;
                else if (e.KeyCode == Keys.Down)
                    ((DeformedState)drawBoard.DrawableModel).Scale -= 0.1;

                this.drawBoard.Refresh();
            }
        }

        /// <summary> Копирование картинки в буффер обмена. </summary>
        private void mnuCopyImageToBuffer_Click(object sender, EventArgs e)
        {
            Bitmap bmp = this.drawBoard.GetPicture();
            Clipboard.Clear();
            Clipboard.SetImage(bmp);
        }

        #region Создание моделей

        #region Garteur

        /// <summary> Создание модели Garteur(small)</summary>
        private void Garteur()
        {
            _Model = ModelsFactory.CreateGarterurSmall();
            drawBoard.DrawableModel = _Model;
            drawBoard.Refresh();
            lblModel.Text = "Модель: " + _Model.GetName();
            eigenValuesCache1 = null;
            eigenValuesCache2 = null;
            ClearLists();
        }

        private void mnuGarteur_Sch4_Click(object sender, EventArgs e)
        {
            Garteur();
            GarteurSmall_Selection(4);
        }
      
        private void mnuGarteur_Sch3_Click(object sender, EventArgs e)
        {
            Garteur();
            GarteurSmall_Selection(3);
        }

        private void mnuGarteur_Sch2_Click(object sender, EventArgs e)
        {
            Garteur();
            GarteurSmall_Selection(2);
        }

        private void mnuGarteur_Sch1_Click(object sender, EventArgs e)
        {
            Garteur();
            GarteurSmall_Selection(1);
        }

        private void mnuGarteur_NoSch_Click(object sender, EventArgs e)
        {
            Garteur();
        }

        private void GarteurSmall_Selection(int schema)
        {
            switch (schema)
            {
                case 4:
                    _Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(12).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(13).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(8).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(9).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(4).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(5).SelectDegrees(true, true, false);
                    break;
                case 3:
                    _Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(10).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(11).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(4).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(5).SelectDegrees(true, true, false);
                    break;
                case 2:
                    _Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(8).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(9).SelectDegrees(true, true, false);
                    break;
                case 1:
                    _Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);
                    break;
                default:
                    break;
            }
            this.drawBoard.Refresh();
        }

        #endregion

        #region Балка из 8 секций (Beam8).

        /// <summary> Балка из 8 секций. </summary>
        private void Beam8()
        {
            _Model = ModelsFactory.CreateBeamModel();
            drawBoard.DrawableModel = _Model;
            drawBoard.Refresh();
            lblModel.Text = "Модель: " + _Model.GetName();
            eigenValuesCache1 = null;
            eigenValuesCache2 = null;
            ClearLists();
        }

        private void mnuBeam8_NoSch_Click(object sender, EventArgs e)
        {
            Beam8();
        }

        /// <summary> Балка из 8 секций, схема конденсации "4". </summary>
        private void mnuBeam8_Sch4_Click(object sender, EventArgs e)
        {
            Beam8();
            Beam8_Selection(4);
        }

        /// <summary> Балка из 8 секций, схема конденсации "3". </summary>
        private void mnuBeam8_Sch3_Click(object sender, EventArgs e)
        {
            Beam8();
            Beam8_Selection(3);
        }

        /// <summary> Балка из 8 секций, схема конденсации "2". </summary>
        private void mnuBeam8_Sch2_Click(object sender, EventArgs e)
        {
            Beam8();
            Beam8_Selection(2);
        }

        /// <summary> Балка из 8 секций, схема конденсации "1". </summary>
        private void mnuBeam8_Sch1_Click(object sender, EventArgs e)
        {
            Beam8();
            Beam8_Selection(1);
        }

        private void Beam8_Selection(int schema)
        {
            switch (schema)
            {
                case 4:
                    _Model.GetNodeBySystemIndex(1).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(3).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(5).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(7).SelectDegrees(true, true, false);
                    break;
                case 3:
                    _Model.GetNodeBySystemIndex(2).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(4).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(6).SelectDegrees(true, true, false);
                    break;
                case 2:
                    _Model.GetNodeBySystemIndex(3).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(5).SelectDegrees(true, true, false);
                    break;
                case 1:
                    _Model.GetNodeBySystemIndex(4).SelectDegrees(true, true, false);
                    break;
                default:
                    break;
            }
            this.drawBoard.Refresh();
        }

        #endregion

        #region BeamGarteur

        /// <summary> Создание модели балочный Garteur.</summary>
        private void BeamGarteur()
        {
            _Model = ModelsFactory.CreateBeamGarterur();
            drawBoard.DrawableModel = _Model;
            drawBoard.Refresh();
            lblModel.Text = "Модель: " + _Model.GetName();
            eigenValuesCache1 = null;
            eigenValuesCache2 = null;
            ClearLists();
        }

        private void mnuBeamGarteur_Sch4_Click(object sender, EventArgs e)
        {
            BeamGarteur();
            BeamGarteur_Selection(4);
        }

        private void mnuBeamGarteur_Sch3_Click(object sender, EventArgs e)
        {
            BeamGarteur();
            BeamGarteur_Selection(3);
        }

        private void mnuBeamGarteur_Sch2_Click(object sender, EventArgs e)
        {
            BeamGarteur();
            BeamGarteur_Selection(2);
        }

        private void mnuBeamGarteur_Sch1_Click(object sender, EventArgs e)
        {
            BeamGarteur();
            BeamGarteur_Selection(1);
        }

        private void mnuBeamGarteur_NoSch_Click(object sender, EventArgs e)
        {
            BeamGarteur();
        }

        private void BeamGarteur_Selection(int schema)
        {
            switch (schema)
            {
                case 4:
                    _Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(12).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(13).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(8).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(9).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(4).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(5).SelectDegrees(true, true, false);
                    break;
                case 3:
                    _Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(10).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(11).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(4).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(5).SelectDegrees(true, true, false);
                    break;
                case 2:
                    _Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(8).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(9).SelectDegrees(true, true, false);
                    break;
                case 1:
                    _Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
                    _Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);
                    break;
                default:
                    break;
            }
            this.drawBoard.Refresh();
        }

        #endregion

        #endregion

        #region Создание анализаторов

        /// <summary> Полный расчёт модели фермы без учёта повортных степеней свободы (XY). </summary>
        private void mnuFrameAnalyser_XY_DM_Click(object sender, EventArgs e)
        {
            if (_Model != null)
            {
                AnalyserChoosing ach = new AnalyserChoosing();
                ach.ShowDialog();
                if (ach.DialogResult == DialogResult.OK)
                {
                    if (ach.Analyser == AnalyserNumber.One)
                    {
                        _Analyser1 = new FrameAnalyser_XY_DM(_Model, "Frame Analyser");
                        _Analyser1.UseExistingIndexation = true;
                        lblAnalyser1.Text = "Анализатор 1: " + _Analyser1.Name;
                        eigenValuesCache1 = null;
                    }
                    else
                    {
                        _Analyser2 = new FrameAnalyser_XY_DM(_Model, "Frame Analyser");
                        _Analyser2.UseExistingIndexation = true;
                        lblAnalyser2.Text = "Анализатор 2: " + _Analyser2.Name;
                        eigenValuesCache2 = null;
                    }
                }
            }
        }

        /// <summary> Полный расчёт модели фермы (XY). </summary>
        private void mnuTrussAnalyser_XY_DM_Click(object sender, EventArgs e)
        {
            if (_Model != null)
            {
                AnalyserChoosing ach = new AnalyserChoosing();
                ach.ShowDialog();
                if (ach.DialogResult == DialogResult.OK)
                {
                    if (ach.Analyser == AnalyserNumber.One)
                    {
                        _Analyser1 = new TrussAnalyser_XY_DM(_Model, "Truss Analyser");
                        _Analyser1.UseExistingIndexation = true;
                        lblAnalyser1.Text = "Анализатор 1: " + _Analyser1.Name;
                        eigenValuesCache1 = null;
                    }
                    else
                    {
                        _Analyser2 = new TrussAnalyser_XY_DM(_Model, "Truss Analyser");
                        _Analyser2.UseExistingIndexation = true;
                        lblAnalyser2.Text = "Анализатор 2: " + _Analyser2.Name;
                        eigenValuesCache2 = null;
                    }
                }
            }
        }

        /// <summary> Статическая конденсация с дискретной матрицей масс, XY. </summary>
        private void mnuStaticCondensation_Click(object sender, EventArgs e)
        {
            if (_Model != null)
            {
                AnalyserChoosing ach = new AnalyserChoosing();
                ach.ShowDialog();
                if (ach.DialogResult == DialogResult.OK)
                {
                    if (ach.Analyser == AnalyserNumber.One)
                    {
                        _Analyser1 = new StaticCondensation_XY_DM(_Model, "Static condensation");
                        _Analyser1.UseExistingIndexation = true;
                        lblAnalyser1.Text = "Анализатор 1: " + _Analyser1.Name;
                        eigenValuesCache1 = null;
                    }
                    else
                    {
                        _Analyser2 = new StaticCondensation_XY_DM(_Model, "Static condensation");
                        _Analyser2.UseExistingIndexation = true;
                        lblAnalyser2.Text = "Анализатор 2: " + _Analyser2.Name;
                        eigenValuesCache2 = null;
                    }
                }
            }
            _Model.DrawAsFrame = false;
        }
        
        /// <summary> IRS. </summary>
        private void mnuIRS_Click(object sender, EventArgs e)
        {
            if (_Model != null)
            {
                AnalyserChoosing ach = new AnalyserChoosing();
                ach.ShowDialog();
                if (ach.DialogResult == DialogResult.OK)
                {
                    if (ach.Analyser == AnalyserNumber.One)
                    {
                        _Analyser1 = new IRS_XY_DM(_Model, "IRS");
                        _Analyser1.UseExistingIndexation = true;
                        lblAnalyser1.Text = "Анализатор 1: " + _Analyser1.Name;
                        eigenValuesCache1 = null;
                    }
                    else
                    {
                        _Analyser2 = new IRS_XY_DM(_Model, "IRS");
                        _Analyser2.UseExistingIndexation = true;
                        lblAnalyser2.Text = "Анализатор 2: " + _Analyser2.Name;
                        eigenValuesCache2 = null;
                    }
                }
            }
            _Model.DrawAsFrame = false;
        }

        /// <summary> Блочная динамическая конденсация. </summary>
        private void mnuBlockDynamicCondensationKinv_XY_DM_Click(object sender, EventArgs e)
        {
            if (_Model != null)
            {
                AnalyserChoosing ach = new AnalyserChoosing();
                ach.ShowDialog();
                if (ach.DialogResult == DialogResult.OK)
                {
                    if (ach.Analyser == AnalyserNumber.One)
                    {
                        _Analyser1 = new BlockDynamicCondensationKinv_XY_DM(_Model, "Block Dyn. K inv. Condensation");
                        _Analyser1.UseExistingIndexation = true;
                        lblAnalyser1.Text = "Анализатор 1: " + _Analyser1.Name;
                        eigenValuesCache1 = null;
                    }
                    else
                    {
                        _Analyser2 = new BlockDynamicCondensationKinv_XY_DM(_Model, "Block Dyn. K inv. Condensation");
                        _Analyser2.UseExistingIndexation = true;
                        lblAnalyser2.Text = "Анализатор 2: " + _Analyser2.Name;
                        eigenValuesCache2 = null;
                    }
                }
            }
            _Model.DrawAsFrame = false;

            //// 4
            //_Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(12).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(13).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(8).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(9).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(4).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(5).SelectDegrees(true, true, false);

            //// 3
            //_Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(10).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(11).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(4).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(5).SelectDegrees(true, true, false);

            //// 2
            //_Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(8).SelectDegrees(true, true, false);
            //_Model.GetNodeBySystemIndex(9).SelectDegrees(true, true, false);

            // 1
            _Model.GetNodeBySystemIndex(16).SelectDegrees(true, true, false);
            _Model.GetNodeBySystemIndex(17).SelectDegrees(true, true, false);

            this.drawBoard.Refresh();
        }

        private void mnublockDynamicCondensation_XY_DM_Click(object sender, EventArgs e)
        {
            if (_Model != null)
            {
                AnalyserChoosing ach = new AnalyserChoosing();
                ach.ShowDialog();
                if (ach.DialogResult == DialogResult.OK)
                {
                    if (ach.Analyser == AnalyserNumber.One)
                    {
                        _Analyser1 = new BlockDynamicCondensation_XY_DM(_Model, "Block Dyn. Condensation");
                        _Analyser1.UseExistingIndexation = true;
                        lblAnalyser1.Text = "Анализатор 1: " + _Analyser1.Name;
                        eigenValuesCache1 = null;
                    }
                    else
                    {
                        _Analyser2 = new BlockDynamicCondensation_XY_DM(_Model, "Block Dyn. Condensation");
                        _Analyser2.UseExistingIndexation = true;
                        lblAnalyser2.Text = "Анализатор 2: " + _Analyser2.Name;
                        eigenValuesCache2 = null;
                    }
                }
            }
            _Model.DrawAsFrame = false;

            this.drawBoard.Refresh();
        }

        /// <summary> Последовательная частотно-динамическая конденсация. </summary>
        private void mnuSeqDynamicCondensation_Click(object sender, EventArgs e)
        {

        }

        #endregion

        /// <summary> Создание таблицы корреляции СВ. </summary>
        private void btnCorrelationTable_Click(object sender, EventArgs e)
        {
            if (_Model != null && _Analyser1 != null && _Analyser2 != null && eigenValuesCache1 != null && eigenValuesCache2 != null)
            {
                CorrelationTable ct = new CorrelationTable(eigenValuesCache1.Count, eigenValuesCache2.Count);
                
                //функция расчёта корреляции
                Hashtable hash = new Hashtable();
                Func<List<double>, List<double>, int, int, double> Correlation = (evecA, evecB, ia, ib) => 
                {
                    #region function body
		            double avgA = 0, avgB = 0;
                    //Получение среднего для векторов
                    if (hash.ContainsKey(ia))
                        avgA = (double)hash[ia];
                    else
                    {
                        for (int i = 0; i < evecA.Count; i++)
			                avgA += evecA[i];
                        avgA /= evecA.Count;
                        hash.Add(ia, avgA);
                    }
                    if (hash.ContainsKey(ib + 100000))
                        avgB = (double)hash[ib + 100000];
                    else
                    {
                        for (int i = 0; i < evecB.Count; i++)
			                avgB += evecB[i];
                        avgB /= evecB.Count;
                        hash.Add(ib + 100000, avgB);
                    }

                    //расчёт числителя
                    double nom = 0;
                    for (int i = 0; i < evecA.Count; i++)
                        nom += (evecA[i] - avgA) * (evecB[i] - avgB);

			        //расчёт знаменателя
                    double denom1 = 0, denom2 = 0, denom = 0;
                    for (int i = 0; i < evecA.Count; i++)
                    {
                        denom1 += (evecA[i] - avgA) * (evecA[i] - avgA);
                        denom2 += (evecB[i] - avgB) * (evecB[i] - avgB);
                    }
                    denom = Math.Sqrt(denom1 * denom2);

                    return nom / denom; 
	                #endregion
                };


                //заполнение заголовков
                for (int i = 0; i < eigenValuesCache1.Count; i++)
                    ct.SetFirstColValue(i, eigenValuesCache1[i]);
                for (int i = 0; i < eigenValuesCache2.Count; i++)
                    ct.SetHeaderValue(i, eigenValuesCache2[i]);

                //расчёт корреляций СВ и погрешностей СЗ
                List<double> evec1;
                List<double> evec2;
                for (int i = 0; i < eigenValuesCache1.Count; i++)
                {
                    evec1 = _Analyser1.GetFullEigenVecsListForEigenValue(eigenValuesCache1[i]);
                    for (int j = 0; j < eigenValuesCache2.Count; j++)
                    {
                        evec2 = _Analyser2.GetFullEigenVecsListForEigenValue(eigenValuesCache2[j]);
                        double eval_error = (eigenValuesCache1[i] - eigenValuesCache2[j]) / eigenValuesCache1[i];

                        ct.SetCorrelation(i, j, Correlation(evec1, evec2, i, j), eval_error);
                    }
                }
                ct.CopyToClipBoard();
            }

        }

        #region Не используемые

        private void mnuCadre_Click(object sender, EventArgs e)
        {
            //_Model = new Model();
            //_Analyser1 = new FrameAnalyser_XY_DM(_Model);
            //_Analyser1.UseExistingIndexation = true;

            //BarPhysicalProperties p = new BarPhysicalProperties(2.06829e11, 256135, 1.85187e-5, 2.85785e-11);

            //float L = 0.2413F;
            //_Model.CreateNode(0, 0, 0).CreateSupport(true, true, true);
            //_Model.CreateNode(0, L, 1);
            //_Model.CreateNode(L, L, 2);
            //_Model.CreateNode(L, 0, 3).CreateSupport(true, true, true);

            //_Model.CreateBar(_Model.GetNodeByUniqueIndex(0), _Model.GetNodeByUniqueIndex(1), p);
            //_Model.CreateBar(_Model.GetNodeByUniqueIndex(1), _Model.GetNodeByUniqueIndex(2), p);
            //_Model.CreateBar(_Model.GetNodeByUniqueIndex(2), _Model.GetNodeByUniqueIndex(3), p);

            //drawBoard.DrawableModel = _Model;
        }

        #endregion

        private void evalsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (drawBoard.DrawableModel is DeformedState)
                drawBoard.DrawableModel = _Model;
        }

        private void mnuMagic_Click(object sender, EventArgs e)
        {
            double[] evc = new double[] {   0.537553759217676 ,
                                            -0.076253635712566 ,
                                            -0.661893404911808 ,
                                            -0.136029771007684 ,
                                            0.022005080830562 ,
                                            0.119928150311476 ,
                                            0.035932494231554 ,
                                            0.144516002205284 ,
                                            -0.018722603921728 ,
                                            -0.077826459388178 ,
                                            0.000307249367739 ,
                                            0.113743658148692 ,
                                            0.014752783969615 ,
                                            -0.200335629903649 ,
                                            0.023816623627790 ,
                                            -0.033321779052396 ,
                                            0.018303067779757 ,
                                            0.046991612696333 ,
                                            0.003091489122327 ,
                                            -0.079502205935870 ,
                                            -0.003309744558210 ,
                                            0.235359377090648 ,
                                            -0.018503738549110 ,
                                            -0.087431401897681 ,
                                            -0.019148229836735 ,
                                            -0.004603321289807 ,
                                            -0.013051585825549 ,
                                            0.024742136649554 ,
                                            0.017215488088501 ,
                                            -0.199420630212645 ,
                                            0.023677579501981 ,
                                            0.190093701186882   
                                        };

            DeformedState deformedState = new FrameDeformedState();
            deformedState.AssignToModel(_Model);
            int counter = 0;
            double dx, dy;
            for (int i = 0; i < _Model.GetNodesCount(); i++)
            {
                Node node = _Model.GetNodeBySystemIndex(i);
                if (!node.Support.Sx)
                    dx = evc[counter++];
                else
                    dx = 0;
                if (!node.Support.Sy)
                    dy = evc[counter++];
                else
                    dy = 0;

                NodeDisplacement nodeDisplacement = new NodeDisplacement(node, dx, dy, 0);
                deformedState.Add(i, nodeDisplacement);
            }
            drawBoard.DrawableModel = deformedState;
        }
        

    }
}
